home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / glibc-1.09 / glibc-1 / glibc-1.09.1 / sysdeps / mach / hurd / sysd-stdio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-30  |  5.9 KB  |  243 lines

  1. /* Copyright (C) 1994 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <errno.h>
  21. #include <stdio.h>
  22. #include <sys/types.h>
  23. #include <hurd.h>
  24. #include <fcntl.h>
  25. #include <hurd/fd.h>
  26.  
  27.  
  28. /* Check ERR for wanting to generate a signal.  */
  29.  
  30. int __stdio_fileno (void *);
  31.  
  32. static inline int
  33. fd_fail (struct hurd_fd *fd, error_t err)
  34. {
  35.   int signo = _hurd_fd_error_signal (err);
  36.   if (signo)
  37.     _hurd_raise_signal (NULL, signo, __stdio_fileno (fd), err);
  38.   errno = err;
  39.   return -1;
  40. }
  41.  
  42.  
  43. /* Read up to N chars into BUF from COOKIE.
  44.    Return how many chars were read, 0 for EOF or -1 for error.  */
  45. ssize_t
  46. DEFUN(__stdio_read, (cookie, buf, n),
  47.       PTR cookie AND register char *buf AND size_t n)
  48. {
  49.   error_t err;
  50.   struct hurd_fd *fd = cookie;
  51.  
  52.   if (! fd)
  53.     return __hurd_fail (EBADF);
  54.  
  55.   if (err = _hurd_fd_read (fd, buf, &n))
  56.     return fd_fail (fd, err);
  57.  
  58.   return n;
  59. }
  60.  
  61. /* Write up to N chars from BUF to COOKIE.
  62.    Return how many chars were written or -1 for error.  */
  63. ssize_t
  64. DEFUN(__stdio_write, (cookie, buf, n),
  65.       PTR cookie AND register CONST char *buf AND size_t n)
  66. {
  67.   error_t err;
  68.   size_t wrote, nleft;
  69.   struct hurd_fd *fd = cookie;
  70.  
  71.   if (! fd)
  72.     return __hurd_fail (EBADF);
  73.  
  74.   nleft = n;
  75.   do
  76.     {
  77.       wrote = nleft;
  78.       if (err = _hurd_fd_write (fd, buf, &wrote))
  79.     return fd_fail (fd, err);
  80.       buf += wrote;
  81.       nleft -= wrote;
  82.     } while (nleft > 0);
  83.  
  84.   return wrote;
  85. }
  86.  
  87. /* Move COOKIE's file position *POS bytes, according to WHENCE.
  88.    The current file position is stored in *POS.
  89.    Returns zero if successful, nonzero if not.  */
  90. int
  91. DEFUN(__stdio_seek, (cookie, pos, whence),
  92.       PTR cookie AND fpos_t *pos AND int whence)
  93. {
  94.   error_t err;
  95.   struct hurd_fd *fd = cookie;
  96.   if (! fd)
  97.     return __hurd_fail (EBADF);
  98.   __spin_lock (&fd->port.lock);
  99.   err = HURD_FD_PORT_USE (fd, __io_seek (port, *pos, whence, pos));
  100.   return err ? fd_fail (fd, err) : 0;
  101. }
  102.  
  103. /* Close the file associated with COOKIE.
  104.    Return 0 for success or -1 for failure.  */
  105. int
  106. DEFUN(__stdio_close, (cookie), PTR cookie)
  107. {
  108.   error_t error;
  109.   if (cookie)
  110.     error = _hurd_fd_close (cookie);
  111.   else
  112.     error = EBADF;
  113.   return error ? __hurd_fail (error) : 0;
  114. }
  115.  
  116.  
  117. static inline int
  118. modeflags (__io_mode m)
  119. {
  120.   int flags = 0;
  121.   if (m.__read)
  122.     flags |= O_READ;
  123.   if (m.__write)
  124.     flags |= O_WRITE;
  125.   if (m.__append)
  126.     flags |= O_APPEND;
  127.   if (m.__create)
  128.     flags |= O_CREAT;
  129.   if (m.__truncate)
  130.     flags |= O_TRUNC;
  131.   if (m.__exclusive)
  132.     flags |= O_EXCL;
  133.   return flags;
  134. }
  135.  
  136. /* Open FILENAME with the mode in M.  */
  137. int
  138. DEFUN(__stdio_open, (filename, m, cookieptr),
  139.       CONST char *filename AND __io_mode m AND PTR *cookieptr)
  140. {
  141.   int flags;
  142.   file_t port;
  143.   struct hurd_fd *d;
  144.  
  145.   flags = modeflags (m);
  146.   port = __file_name_lookup (filename, flags, 0666 & ~_hurd_umask);
  147.   if (port == MACH_PORT_NULL)
  148.     return -1;
  149.  
  150.   HURD_CRITICAL_BEGIN;
  151.   d = _hurd_alloc_fd (NULL, 0);
  152.   if (d != NULL)
  153.     {
  154.       _hurd_port2fd (d, port, flags);
  155.       __spin_unlock (&d->port.lock);
  156.     }
  157.   HURD_CRITICAL_END;
  158.  
  159.   *cookieptr = d;
  160.   return 0;
  161. }
  162.  
  163.  
  164. /* Open FILENAME with the mode in M.  Use the same magic cookie
  165.    already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN.  */
  166. int
  167. DEFUN(__stdio_reopen, (filename, m, cookieptr),
  168.       CONST char *filename AND __io_mode m AND
  169.       PTR *cookieptr AND __io_close_fn closefn)
  170. {
  171.   int flags;
  172.   file_t port;
  173.   struct hurd_fd *d;
  174.  
  175.   if (closefn != __stdio_close)
  176.     {
  177.       /* The old cookie is Not Of The Body.
  178.      Just close it and do a normal open.  */
  179.       (*closefn) (*cookieptr);
  180.       return __stdio_open (filename, m, cookieptr);
  181.     }
  182.  
  183.   /* Open a new port on the file.  */
  184.   flags = modeflags (m);
  185.   port = __file_name_lookup (filename, flags, 0666 & ~_hurd_umask);
  186.  
  187.   /* Install the new port in the same file descriptor slot the old cookie
  188.      points to.  If opening the file failed, PORT will be MACH_PORT_NULL
  189.      and installing it in the descriptor will have the effect of closing
  190.      the old descriptor.  */
  191.  
  192.   d = *cookieptr;
  193.   HURD_CRITICAL_BEGIN;
  194.   __spin_lock (&d->port.lock);
  195.   _hurd_port2fd (d, port, flags);
  196.   __spin_unlock (&d->port.lock);
  197.   HURD_CRITICAL_END;
  198.  
  199.   return port == MACH_PORT_NULL ? -1 : 0;
  200. }
  201.  
  202.  
  203. /* Write a message to the error output.
  204.    Try hard to make it really get out.  */
  205. void
  206. DEFUN(__stdio_errmsg, (msg, len), CONST char *msg AND size_t len)
  207. {
  208.   io_t server;
  209.   unsigned int wrote;
  210.  
  211.   server = __getdport (2);
  212.   __io_write (server, msg, len, -1, &wrote);
  213.   __mach_port_deallocate (__mach_task_self (), server);
  214. }
  215.  
  216.  
  217. /* Return the POSIX.1 file descriptor associated with COOKIE,
  218.    or -1 for errors.  If COOKIE does not relate to any POSIX.1 file
  219.    descriptor, this should return -1 with errno set to EOPNOTSUPP.  */
  220. int
  221. DEFUN(__stdio_fileno, (cookie), PTR cookie)
  222. {
  223.   int fd;
  224.  
  225.   if (! cookie)
  226.     return __hurd_fail (EBADF);
  227.  
  228.   __mutex_lock (&_hurd_dtable_lock);
  229.   for (fd = 0; fd < _hurd_dtablesize; ++fd)
  230.     if (_hurd_dtable[fd] == cookie)
  231.       {
  232.     __mutex_unlock (&_hurd_dtable_lock);
  233.     return fd;
  234.       }
  235.   __mutex_unlock (&_hurd_dtable_lock);
  236.  
  237.   /* This should never happen, because this function should not be
  238.      installed as a stream's __fileno function unless that stream's cookie
  239.      points to a file descriptor.  */
  240.   errno = EGRATUITOUS;
  241.   return -1;
  242. }
  243.